package com.example.user.customviewdemo.drawing.xfermode;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Xfermode;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by user on 2016/5/5.
 * 绘制目标dstBtmap和源srcBitmap图形混合的PorterDuffXfermode 的 16种Mode模式
 */
public class PorterDuffXfermodeView extends View {
    private int width = 150;
    private int height = 150;
    private float cellWidth = 1.5f*width+30,cellHeight = 1.5f*height+150;

    private int row = 4;

    private Bitmap dstBmp, srcBmp;
    private Paint paint;

    private static final Xfermode[] sModes = {
            new PorterDuffXfermode(PorterDuff.Mode.CLEAR),
            new PorterDuffXfermode(PorterDuff.Mode.SRC),
            new PorterDuffXfermode(PorterDuff.Mode.DST),
            new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),
            new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),
            new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),
            new PorterDuffXfermode(PorterDuff.Mode.DST_IN),
            new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),
            new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),
            new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),
            new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),
            new PorterDuffXfermode(PorterDuff.Mode.XOR),
            new PorterDuffXfermode(PorterDuff.Mode.DARKEN),
            new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),
            new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),
            new PorterDuffXfermode(PorterDuff.Mode.SCREEN)
    };

    private static final String[] sLabels = {
            "Clear", "Src", "Dst", "SrcOver",
            "DstOver", "SrcIn", "DstIn", "SrcOut",
            "DstOut", "SrcATop", "DstATop", "Xor",
            "Darken", "Lighten", "Multiply", "Screen"
    };

    public PorterDuffXfermodeView(Context context) {
        super(context);
    }

    public PorterDuffXfermodeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(3);
        paint.setTextSize(50);
        paint.setTextAlign(Paint.Align.CENTER);
        dstBmp = mkDstBmp(width,height);
        srcBmp = mkSrcBmp(width,height);
        //关闭硬件加速
        setLayerType(View.LAYER_TYPE_SOFTWARE,null);
    }

    public PorterDuffXfermodeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        /**
         *  源图像在运算时，只是在源图像所在区域与对应区域的目标图像做运算。
         *  所以目标图像与源图像不相交的地方是不会参与运算的！这一点非常重要！
         *  不相交的地方不会参与运算，所以不相交的地方的图像也不会是脏数据，也不会被更新，
         *  所以不相交地方的图像也永远显示的是目标图像。
         */

        //开始离屏绘制  参数决定离屏绘制的区域
        float y = 0;
        float x = 0;

        for (int i = 0; i < sModes.length; i++) {
            //表示生成一个新的layer图层（使用Xfermode必须要使用），canvas缺省默认为一个layer图层，
           int layerID = canvas.saveLayer(0,0,getWidth(),getHeight(),null,Canvas.ALL_SAVE_FLAG);
            canvas.translate(x,y);
            canvas.drawRect(0,0,1.5f*width,1.5f*height,paint);
            canvas.drawBitmap(dstBmp,0,0,paint);
            canvas.drawText(sLabels[i],cellWidth/2,cellHeight-100,paint);
            paint.setXfermode(sModes[i]);
            canvas.drawBitmap(srcBmp,width/2,height/2,paint);
            paint.setXfermode(null);//一定要加上这行代码，不然会出现意想不到的结果，归根到底是因为这里是重用的一个paint
           canvas.restoreToCount(layerID);

           x += cellWidth;
            if(i%row == row - 1){
                x = 0;
                y += cellHeight;
            }
        }


    }

    /**
     * 构造一个圆的，存色的bitmap（dstBmp）
     * @param width
     * @param height
     * @return
     */
    private Bitmap mkDstBmp(int width, int height) {
        Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bmp);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(0xFFFECC44);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            canvas.drawOval(0, 0, width, height, paint);
        }
        return bmp;
    }

    /**
     * 构造一个矩形纯色srcBmp
     * @param width
     * @param height
     * @return
     */
    private Bitmap mkSrcBmp(int width, int height) {
        Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bmp);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(0xFF66AAFF);
        canvas.drawRect(0, 0, width, height, paint);
        return bmp;
    }
}
